<?php
//Incluindo classes associadas a esse modelo
include_once MODELS."venda.php";
include_once MODELS."cliente.php";
include_once MODELS."localidade.php";

/**
 * Essa classe implementa o modelo da entidade Parcela.
 * @author Emanuel Oliveira <emanuel.oliveira23@gmail.com>
 */
class ParcelaModel extends Database {
    
    /**
     * Nome da tabela de parcelas no banco de dados 
     */
    const TABLE = "venda_parcela";
    
    /**
     * Nome da coluna do numero da parcela no banco de dados.
     */
    const NUMERO    = "numero_parcela";
    
    /**
     * Nome da coluna da data de vencimento da parcela no banco de dados.
     */
    const VALIDADE  = "data_parcela";
    
    /**
     * Nome da coluna da data de adiamento da cobrança de uma parcela no banco de dados
     */
    const REMARCACAO = "data_remarcacao"; 
    
    /**
     * Nome da coluna do valor da parcela no banco de dados.
     */
    const VALOR     = "valor_parcela";
    
    /**
     * Nome da coluna do status da parcela no banco de dados.
     */
    const STATUS    = "status_parcela";
    
    /**
     * Nome da coluna do identificador da venda da parcela no banco de dados.
     */
    const VENDA     = "id_venda";
    
    /**
     * Seleciona uma lista de parcelas com os <i>fields</i> preenchidos com os valores do banco.
     * @param mixed $fields colunas da seleção, pode ser um array (utilize as constantes das colunas).
     * @param string $condition filtra a seleção das linhas, se for <i>null</i> não será considerado.
     * @return array lista de parcelas do tipo Parcela.
     */
    public function select($fields = " * ", $condition = null) {
        if(is_array($fields)) $fields = implode(",", $fields);
        $res = parent::select(self::TABLE, $fields, $condition);
        $anna = $this->getAnnalisses();
        $parcelas = array();
        while(($row = $anna->fetchObject($res)) !== FALSE){
            $parcelas[] = new Parcela(
                            isset($row->{self::NUMERO})?$row->{self::NUMERO}:0,
                            isset($row->{self::VALIDADE})?$row->{self::VALIDADE}:"",
                            isset($row->{self::REMARCACAO})?$row->{self::REMARCACAO}:"",
                            isset($row->{self::VALOR})?$row->{self::VALOR}:0,
                            isset($row->{self::STATUS})?$row->{self::STATUS}: false,
                            isset($row->{self::VENDA})?$row->{self::VENDA}: 0
                          );
        }
        return $parcelas;
    }
    
    /**
     * Seleciona uma lista de identificadores de localidades de uma rota que possuem parcelas
     * de vendas atrasadas no periodo informado.
     * @param int $id_rota identificador da rota.
     * @param string $limit_up_date data limite superior da data da parcela
     * @param string $limit_down_date data limite inferior da data da parcela
     * @return array lista de identificadores de localidades com vendas com parcelas atrasadas
     */
    public function selectForRota($id_rota, $limit_up_date, $limit_down_date = ''){
        
        $field = "DISTINCT(".LocalidadeModel::TABLE.".".LocalidadeModel::ID.")";
        
        $joins[] = "LEFT JOIN ".VendaModel::TABLE." ON ".self::TABLE.".".self::VENDA." = ".VendaModel::TABLE.".".VendaModel::ID;
        $joins[] = "LEFT JOIN ".ClienteModel::TABLE." ON ".VendaModel::CLIENTE." = ".ClienteModel::TABLE.".".ClienteModel::ID;
        $joins[] = "LEFT JOIN ".LocalidadeModel::TABLE." ON ".ClienteModel::TABLE.".".ClienteModel::LOCALIDADE." = ".LocalidadeModel::TABLE.".".LocalidadeModel::ID;
        
        
        $condition  = LocalidadeModel::ROTA." = $id_rota AND ".self::STATUS." = 0 AND ( ";
        
        $condition .= "( ".self::REMARCACAO." IS NULL AND ( ".self::VALIDADE." <= '$limit_up_date' ".( !empty($limit_down_date) ? " AND ".self::VALIDADE." >= '$limit_down_date' " : " " ).") )"; 
        $condition .= " OR ";
        $condition .= " ( ".self::REMARCACAO." IS NOT  NULL AND ( ".self::REMARCACAO." <= '$limit_up_date' ".( !empty($limit_down_date) ? " AND ".self::REMARCACAO." >= '$limit_down_date' " : " " ).") )"; 
        
        $condition .= " ) AND ".VendaModel::TABLE.".".VendaModel::STATUS." = ".VendaModel::STATUS_ATIVA;
        $condition .= " AND ".VendaModel::TABLE.".".VendaModel::DT_ENTREGA." IS NOT NULL ";
        $condition .= " ORDER BY ".LocalidadeModel::SEQ_ROTA; 
        
        $res = parent::select(self::TABLE." ".implode(" ", $joins), $field, $condition);
        $ana = $this->getAnnalisses();
        $localidades = array();
        while (($row = $ana->fetchObject($res)) !== FALSE){
            $localidades[] = $row->id;
        }
        
        return $localidades;
        
    }
    
    /**
     * Seleciona uma lista de identificadores de vendas de uma localidade que possuem parcelas
     * de vendas atrasadas no periodo informado.
     * @param int $localidade_id identificador da localidade.
     * @param string $limit_up_date data limite superior da data da parcela
     * @param string $limit_down_date data limite inferior da data da parcela     
     * @return array lista de identificadores de vendas com parcelas atrasadas
     */
    public function selectForLocalidade($localidade_id, $limit_up_date, $limit_down_date = ''){
        
        $field = "DISTINCT(".self::VENDA.")";
        
        $joins[] = "LEFT JOIN ".VendaModel::TABLE." ON ".self::TABLE.".".self::VENDA." = ".VendaModel::TABLE.".".VendaModel::ID;
        $joins[] = "LEFT JOIN ".ClienteModel::TABLE." ON ".VendaModel::CLIENTE." = ".ClienteModel::TABLE.".".ClienteModel::ID;
        
        $condition  = ClienteModel::LOCALIDADE." = $localidade_id AND ".self::STATUS." = 0 ";
        $condition .= " AND ".VendaModel::TABLE.".".VendaModel::STATUS." = ".VendaModel::STATUS_ATIVA;
        $condition .= " AND ".VendaModel::TABLE.".".VendaModel::DT_ENTREGA." IS NOT NULL AND (";
        
        $condition .= "( ".self::REMARCACAO." IS NULL AND ( ".self::VALIDADE." <= '$limit_up_date' ".( !empty($limit_down_date) ? " AND ".self::VALIDADE." >= '$limit_down_date' " : " " ).") )"; 
        $condition .= " OR ";
        $condition .= " ( ".self::REMARCACAO." IS NOT NULL AND ( ".self::REMARCACAO." <= '$limit_up_date' ".( !empty($limit_down_date) ? " AND ".self::REMARCACAO." >= '$limit_down_date' " : " " ).") )"; 
        $condition .= " ) ";
        
        $res = parent::select(self::TABLE." ".implode(" ", $joins), $field, $condition);
        $ana = $this->getAnnalisses();
        $localidades = array();
        while (($row = $ana->fetchObject($res)) !== FALSE){
            $localidades[] = $row->{self::VENDA};
        }
        
        return $localidades;
    }
    
    /**
     * Seleciona uma lista de parcelas de parcelas atrasadas de uma regiao
     * @param int $id_rota identificador da rota.
     * @param string $limit_date data limite da data da venda
     * @return array lista de parcelas atrasadas
     */
    public function selectForRegiao($regiao, $limit_date){
        
        $field = self::VENDA.",".self::NUMERO.",".self::VALOR;
        
        $joins[] = "LEFT JOIN ".VendaModel::TABLE." ON ".self::TABLE.".".self::VENDA." = ".VendaModel::TABLE.".".VendaModel::ID;
        $joins[] = "LEFT JOIN ".ClienteModel::TABLE." ON ".VendaModel::CLIENTE." = ".ClienteModel::TABLE.".".ClienteModel::ID;
        $joins[] = "LEFT JOIN ".LocalidadeModel::TABLE." ON ".ClienteModel::LOCALIDADE." = ".LocalidadeModel::TABLE.".".LocalidadeModel::ID;
        $joins[] = "LEFT JOIN ".RotaModel::TABLE." ON ".LocalidadeModel::ROTA." = ".RotaModel::TABLE.".".RotaModel::ID;
        
        $condition  = RotaModel::REGIAO." = $regiao "; 
        $condition .= " AND ".self::STATUS." = 0 ";
        $condition .= " AND '$limit_date' > ".self::VALIDADE;
        
        $res = parent::select(self::TABLE." ".implode(" ", $joins), $field, $condition);
        $ana = $this->getAnnalisses();
        $parcelas = array();
        while (($row = $ana->fetchObject($res)) !== FALSE){
            $parcela            = new Parcela();
            $parcela->numero    = $row->{self::NUMERO};
            $parcela->venda     = $row->{self::VENDA};
            $parcela->valor     = $row->{self::VALOR};
            $parcelas[]         = $parcela;
        }
        
        return $parcelas;
    }
    
    /**
     * Insere uma parcela na base de dados.
     * @param Parcela $parcela parcela que vai ser inserida
     * @return bool true em caso de sucesso na inserção ou false em caso de falha
     */
    public function insert(Parcela $parcela) {
        $fields = implode(",", array( self::NUMERO, self::VALIDADE, self::REMARCACAO,
                                      self::VALOR, self::STATUS, self::VENDA ));
        $vars = get_object_vars($parcela);
        return parent::insert(self::TABLE, $fields, Database::turnInValues($vars));
    }
    
    /**
     * Insere uma lista parcelas na base de dados.
     * @param array $prodVenda parcelas (array de Parcelas) que vão ser inseridas
     * @return bool true em caso de sucesso na inserção ou false em caso de falha
     */
    public function inserts($arrParcelas){
        if(empty($arrParcelas) || !is_array($arrParcelas)) return false;
        $values = array();
        foreach ($arrParcelas as $parcela){
            $vars = get_object_vars($parcela);
            unset($vars['remarcacao']);
            $values[] = "(".Database::turnInValues($vars).")";
        }
        $fields = implode(",", array( self::NUMERO, self::VALIDADE,
                                      self::VALOR, self::STATUS, self::VENDA ));
        return parent::insert(self::TABLE, $fields, $values);
    }
    
    /**
     * Realiza a remoção de uma parcela.
     * @param Parcela $parcela parcela a ser removida.
     * @return bool true em caso de sucesso, ou false em caso de falha
     */
    public function delete(Parcela $parcela) {
        $condition = self::NUMERO." = {$parcela->numero} AND ".self::VENDA." = {$parcela->venda}";
        return parent::delete(self::TABLE, $condition, true);
    }
    
    /**
     * Atualiza <i>field</i> com <i>value</i> de acordo com <i>condition</i>.
     * @param string $value campo da tabela
     * @param string $value valor a atribuido
     * @param string $condition cláusula WHERE
     * @return bool true em caso de sucesso, ou false em caso de falha
     */
    public function simpleUpdate($field, $value, $condition){
        return parent::update(self::TABLE, $field, $value, $condition);
    }
    
    /**
     * Atualiza <i>parcela</i> de acordo com o seu identificador.
     * @param Parcela $parcela parcela que vai ser aualizada
     * @return bool true em caso de sucesso na atualização ou false em caso de falha
     */
    public function update(Parcela $parcela) {
        $dic = array (
            self::VALIDADE  => $parcela->validade,
            self::REMARCACAO => $parcela->remarcacao,
            self::VALOR     => $parcela->valor,
            self::STATUS    => $parcela->status,
        );
        $condition = self::NUMERO." = {$parcela->numero} AND ".self::VENDA." = {$parcela->venda}";
        return parent::formattedUpdates(self::TABLE, Database::turnInUpdateValues($dic), $condition);
    }
    
}
?>
